
package com.jf.cloud.auth.controller.admin;

import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.jf.cloud.api.auth.bo.UserInfoInTokenBO;
import com.jf.cloud.api.auth.vo.TokenInfoVO;
import com.jf.cloud.api.biz.feign.NotifyFeignClient;
import com.jf.cloud.auth.dto.ForgetPasswordDTO;
import com.jf.cloud.auth.dto.UpdatePasswordDTO;
import com.jf.cloud.auth.manager.PasswordManager;
import com.jf.cloud.auth.manager.TokenStore;
import com.jf.cloud.auth.model.AuthAccount;
import com.jf.cloud.auth.service.AuthAccountService;
import com.jf.cloud.common.cache.util.RedisUtil;
import com.jf.cloud.common.exception.LuckException;
import com.jf.cloud.common.response.ServerResponseEntity;
import com.jf.cloud.common.security.AuthUserContext;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.Objects;

/**
 * @author zz
 * @date 2021/01/29
 */
@RestController("adminPasswordController")
@RequestMapping("/mp/password")
@Tag(name = "管理后台密码修改")
public class PasswordController {

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private AuthAccountService authAccountService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private NotifyFeignClient notifyFeignClient;

    @Autowired
    private PasswordManager passwordManager;

    public static final String CHECK_UPDATE_SMS_FLAG = "checkUpdatePwdSmsFlag";

    @Value("${jfcloud.expose.operation.auth:}")
    private Boolean permission;


    @PutMapping("/update_password")
    @Operation(summary = "更新密码" , description = "更新当前用户的密码, 更新密码之后要退出登录，清理token")
    public ServerResponseEntity<TokenInfoVO> updatePassword(@Valid @RequestBody UpdatePasswordDTO updatePasswordDTO) {
        UserInfoInTokenBO userInfoInToken = AuthUserContext.get();
        Integer sysType = userInfoInToken.getSysType();
        String userName;
        switch (sysType) {
            case 1:
                userName = "home";
                break;
            case 2:
                userName = "admin";
                break;
            case 3:
                userName = "supplier";
                break;
            default:
                userName = "admin";
                break;
        }
        if (Objects.equals(userInfoInToken.getUserName(), userName) && BooleanUtil.isFalse(permission)) {
            throw new LuckException("没有权限进行此操作");
        }
        AuthAccount authAccount = authAccountService.getByUserIdAndType(userInfoInToken.getUserId(), userInfoInToken.getSysType());
        ServerResponseEntity<String> oldPasswordEntity = passwordManager.decryptPassword(updatePasswordDTO.getOldPassword());
        if (!oldPasswordEntity.isSuccess()) {
            return ServerResponseEntity.transform(oldPasswordEntity);
        }
        String oldDecryptPassword = oldPasswordEntity.getData();
        ServerResponseEntity<String> newPasswordEntity = passwordManager.decryptPassword(updatePasswordDTO.getNewPassword());
        if (!newPasswordEntity.isSuccess()) {
            return ServerResponseEntity.transform(newPasswordEntity);
        }
        String newDecryptPassword = newPasswordEntity.getData();
        if (!passwordEncoder.matches(oldDecryptPassword, authAccount.getPassword())) {
            return ServerResponseEntity.showFailMsg("旧密码不正确");
        }


        authAccountService.updatePassword(userInfoInToken.getUserId(), userInfoInToken.getSysType(), newDecryptPassword);

        tokenStore.deleteAllToken(userInfoInToken.getSysType().toString(), userInfoInToken.getUid());
        return ServerResponseEntity.success();
    }

    @PutMapping("/ua/forget_password")
    @Operation(summary = "忘记密码" , description = "通过验证码修改密码，更新密码之后要退出登录，清理token")
    public ServerResponseEntity<TokenInfoVO> password(@Valid @RequestBody ForgetPasswordDTO forgetPasswordDTO) {

        AuthAccount authAccount = authAccountService.getAccountByInputUserName(forgetPasswordDTO.getMobile(), forgetPasswordDTO.getSysType());
        if (authAccount == null) {
            return ServerResponseEntity.showFailMsg("用户不存在");
        }

        String checkUpdatePwdSmsFlag = CHECK_UPDATE_SMS_FLAG + forgetPasswordDTO.getCheckUpdatePwdSmsFlag();
        // 看看有没有校验验证码成功的标识
        if (StrUtil.isBlank(forgetPasswordDTO.getCheckUpdatePwdSmsFlag())) {
            // 验证码已过期，请重新发送验证码校验
            throw new LuckException("验证码已过期，请重新发送验证码校验");
        } else {
            String checkRegisterSmsFlagMobile = RedisUtil.get(checkUpdatePwdSmsFlag);
            if (!Objects.equals(checkRegisterSmsFlagMobile, forgetPasswordDTO.getMobile())) {
                // 验证码已过期，请重新发送验证码校验
                throw new LuckException("验证码已过期，请重新发送验证码校验");
            }
        }

        ServerResponseEntity<String> newPasswordEntity = passwordManager.decryptPassword(forgetPasswordDTO.getNewPassword());
        if (!newPasswordEntity.isSuccess()) {
            return ServerResponseEntity.transform(newPasswordEntity);
        }
        String newDecryptPassword = newPasswordEntity.getData();
        authAccountService.updatePassword(authAccount.getUserId(), authAccount.getSysType(), newDecryptPassword);

        tokenStore.deleteAllToken(authAccount.getSysType().toString(), authAccount.getUid());
        return ServerResponseEntity.success();
    }

}
